package com.nineclock.document.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.dto.DocumentUserDTO;
import com.nineclock.document.enums.DocumentPermissionEnum;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.DocFileService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class DocFileServiceImpl implements DocFileService {

    @Autowired
    private DocFolderMapper folderMapper;
    @Autowired
    private DocFileMapper fileMapper;
    @Autowired
    private SysUserFeign sysUserFeign;
    @Autowired
    private DocCollaborationsMapper collaborationsMapper;

    @Override
    public DocumentDto listFolderAndFile(Long parentFoldId) {
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //查询文件夹列表
        List<DocFolderDto> folders = queryFolders(parentFoldId, companyId);

        //查询文件列表
        List<DocFileDto> files = queryFiles(parentFoldId, companyId);

        //返回
        DocumentDto documentDto = new DocumentDto(folders, files);
        return documentDto;
    }




    private List<DocFileDto> queryFiles(Long parentFoldId, Long companyId) {
        List<DocFile> allFiles = new ArrayList<>();

        //1. 查询 公共读/公共读写权限 的文件
        LambdaQueryWrapper<DocFile> fileWrapper1 = new LambdaQueryWrapper<>();
        fileWrapper1.eq(DocFile::getCompanyId, companyId);
        fileWrapper1.eq(DocFile::getFolderId, parentFoldId);
        fileWrapper1.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(),DocumentPermissionEnum.ALL_READ_WRITE.getPermission());
        fileWrapper1.eq(DocFile::getStatus, (short)1);
        List<DocFile> docFiles1 = fileMapper.selectList(fileWrapper1);


        //2. 查询自己 私有权限 的文件 ----> createUserId
        LambdaQueryWrapper<DocFile> fileWrapper2 = new LambdaQueryWrapper<>();
        fileWrapper2.eq(DocFile::getCompanyId, companyId);
        fileWrapper2.eq(DocFile::getFolderId, parentFoldId);
        fileWrapper2.eq(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        fileWrapper2.eq(DocFile::getStatus, (short)1);

        //文档的创建人就是当前用户
        fileWrapper2.eq(DocFile::getCreateUserId, CurrentUserHolder.get().getCompanyUserId());
        List<DocFile> docFiles2 = fileMapper.selectList(fileWrapper2);


        //3. 当前 用户是协作者 的文件列表
        Long companyUserId = CurrentUserHolder.get().getCompanyUserId();
        List<DocFile> docFiles3 = fileMapper.queryFileByCollaboration(companyUserId, parentFoldId);


        if(CollectionUtil.isNotEmpty(docFiles1)){
            allFiles.addAll(docFiles1);
        }
        if(CollectionUtil.isNotEmpty(docFiles2)){
            allFiles.addAll(docFiles2);
        }
        if(CollectionUtil.isNotEmpty(docFiles3)){
            allFiles.addAll(docFiles3);
        }

        //组装数据并返回
        Set<DocFile> fileSet = new HashSet<>(allFiles);
        Set<DocFileDto> fileDtoSet = BeanHelper.copyWithCollection(fileSet, DocFileDto.class);


        //组装用户名
        List<DocFileDto> files = fileDtoSet.stream().map(docFileDto -> {
            Long createUserId = docFileDto.getCreateUserId(); //创建人
            Long updateUserId = docFileDto.getUpdateUserId(); //更新人

            SysCompanyUserDTO companyUserDTO = sysUserFeign.queryByCompanyUserId(createUserId).getData();
            if (companyUserDTO != null) {
                docFileDto.setUserName(companyUserDTO.getUserName());//创建用户
            }

            SysCompanyUserDTO userDTO = sysUserFeign.queryByCompanyUserId(updateUserId).getData();
            if (userDTO != null) {
                docFileDto.setUpdateUserName(userDTO.getUserName());//更新用户名
            }

            return docFileDto;
        }).collect(Collectors.toList());
        return files;
    }


    private List<DocFolderDto> queryFolders(Long parentFoldId, Long companyId) {
        LambdaQueryWrapper<DocFolder> folderWrapper = new LambdaQueryWrapper<>();
        folderWrapper.eq(DocFolder::getCompanyId, companyId);
        folderWrapper.eq(DocFolder::getParentId, parentFoldId);
        folderWrapper.eq(DocFolder::getStatus, (short)1);

        List<DocFolder> docFolders = folderMapper.selectList(folderWrapper);

        List<DocFolderDto> folders = BeanHelper.copyWithCollection(docFolders, DocFolderDto.class);

        return folders;
    }


    @Override
    public DocFileDto getFileByFileId(Long id) {
        //校验
        if(id == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //根据ID查询
        DocFile docFile = fileMapper.selectById(id);
        return BeanHelper.copyProperties(docFile, DocFileDto.class);
    }


    @Override
    public PageResult<DocumentUserDTO> pagingCollaborations(Long fileId, Integer page, Integer pageSize) {

        //参数校验
        if(fileId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //根据 文档ID 查询文档协作者ID ---------> 100
        Page<DocCollaborations> p = new Page<>(page , pageSize);

        LambdaQueryWrapper<DocCollaborations> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocCollaborations::getFileId, fileId);

        p = collaborationsMapper.selectPage(p, wrapper); //执行分页查询, 获取结果
        List<DocCollaborations> records = p.getRecords();


        //获取 协作者ID 集合
        List<Long> collIds = records.stream().map(docCollaborations -> {
            return docCollaborations.getCollaborationId();
        }).collect(Collectors.toList());


        //组装协作者的信息
        List<DocumentUserDTO> documentUserDTOS = new ArrayList<>();
        for (Long id : collIds) {
            DocumentUserDTO documentUserDTO = new DocumentUserDTO();

            SysCompanyUserDTO userDTO = sysUserFeign.queryByCompanyUserId(id).getData();
            documentUserDTO.setId(id);
            documentUserDTO.setUserName(userDTO.getUserName());

            documentUserDTOS.add(documentUserDTO);
        }

        //返回
        return new PageResult<DocumentUserDTO>(p.getTotal(), p.getPages(), documentUserDTOS);
    }
}
